/*!
 * \file WTSCollection.hpp
 * \project	WonderTrader
 *
 * \author Wesley
 * \date 2020/03/30
 * 
 * \brief WonderTrader集合容器定义文件
 * 
 * \details 本文件定义了WonderTrader框架中的核心集合容器类：
 *          - WTSArray：动态数组容器，支持WTSObject指针管理
 *          - WTSMap：有序映射容器，基于std::map实现
 *          - WTSHashMap：哈希映射容器，基于robin_map实现
 *          - WTSQueue：队列容器，基于std::deque实现
 *          
 *          所有容器都继承自WTSObject，支持引用计数管理。
 *          容器内的对象都会自动进行引用计数管理，确保内存安全。
 */
#pragma once
#include "WTSObject.hpp"
#include <vector>
#include <map>
#include <functional>
#include <algorithm>
#include "../FasterLibs/tsl/robin_map.h"

#include <deque>

NS_WTP_BEGIN

//////////////////////////////////////////////////////////////////////////
//WTSArray

/*!
 * \brief 平台通用数组容器
 * 
 * \details 内部使用vector实现的动态数组容器，专门用于存储WTSObject指针。
 *          具有以下特点：
 *          - 自动引用计数管理：添加对象时自动retain，删除时自动release
 *          - 类型安全：只能存储WTSObject及其派生类
 *          - 跨平台兼容：提供统一的接口
 *          - 高性能：基于std::vector实现
 *          - 支持迭代器：提供正向和反向迭代器
 *          - 支持排序：提供自定义排序函数接口
 * 
 * \author Wesley
 * \date 2020/03/30
 */
class WTSArray : public WTSObject
{
public:
	/*!
	 * \brief 迭代器类型定义
	 */
	typedef std::vector<WTSObject*>::iterator Iterator;							///< 正向迭代器
	typedef std::vector<WTSObject*>::const_iterator ConstIterator;				///< 常量正向迭代器

	typedef std::vector<WTSObject*>::reverse_iterator ReverseIterator;			///< 反向迭代器
	typedef std::vector<WTSObject*>::const_reverse_iterator ConstReverseIterator;	///< 常量反向迭代器

	typedef std::function<bool(WTSObject*, WTSObject*)>	SortFunc;				///< 排序函数类型

	/*!
	 * \brief 创建数组实例
	 * \details 静态工厂方法，创建新的WTSArray实例
	 * \return 新创建的WTSArray指针
	 */
	static WTSArray* create()
	{
		WTSArray* pRet = new WTSArray();
		return pRet;
	}

	/*!
	 * \brief 获取数组长度
	 * \return 数组中元素的数量
	 */
	uint32_t size() const{ return (uint32_t)_vec.size(); }

	/*!
	 * \brief 重设数组大小，预先分配空间
	 * \details 调用该函数可以预先分配长度，预先分配的数据都是NULL
	 * \param _size 新的数组大小
	 */
	void resize(uint32_t _size)
	{
		if(!_vec.empty())
			clear();

		_vec.resize(_size, NULL);
	}

	/*!
	 * \brief 获取数组指定位置的对象
	 * \details 相比grab接口，at接口只取对象引用，不增加对象的引用计数。
	 *          grab接口读取对象后，会增加引用计数。
	 * \param idx 数组索引
	 * \return 指定位置的对象指针，若索引越界则返回NULL
	 */
	WTSObject* at(uint32_t idx)
	{
		if(idx <0 || idx >= _vec.size())
			return NULL;

		WTSObject* pRet = _vec.at(idx);
		return pRet;
	}

	uint32_t idxOf(WTSObject* obj)
	{
		if (obj == NULL)
			return -1;

		uint32_t idx = 0;
		auto it = _vec.begin();
		for (; it != _vec.end(); it++, idx++)
		{
			if (obj == (*it))
				return idx;
		}

		return -1;
	}

	template<typename T> 
	T* at(uint32_t idx)
	{
		if(idx <0 || idx >= _vec.size())
			return NULL;

		WTSObject* pRet = _vec.at(idx);
		return static_cast<T*>(pRet);
	}

	/*!
	 * \brief []操作符重载
	 * \details 用法同at方法
	 * \param idx 数组索引
	 * \return 指定位置的对象指针，若索引越界则返回NULL
	 */
	WTSObject* operator [](uint32_t idx)
	{
		if(idx <0 || idx >= _vec.size())
			return NULL;

		WTSObject* pRet = _vec.at(idx);
		return pRet;
	}

	/*!
	 * \brief 获取数组指定位置的对象并增加引用计数
	 * \details 会增加引用计数，调用者需要负责释放
	 * \param idx 数组索引
	 * \return 指定位置的对象指针（已增加引用计数），若索引越界则返回NULL
	 */
	WTSObject*	grab(uint32_t idx)
	{
		if(idx <0 || idx >= _vec.size())
			return NULL;

		WTSObject* pRet = _vec.at(idx);
		if (pRet)
			pRet->retain();

		return pRet;
	}

	/*!
	 * \brief 向数组末尾追加对象
	 * \details 会自动增加对象的引用计数
	 * \param obj 要追加的对象指针
	 * \param bAutoRetain 是否自动增加引用计数，默认为true
	 */
	void append(WTSObject* obj, bool bAutoRetain = true)
	{
		if (bAutoRetain && obj)
			obj->retain();

		_vec.emplace_back(obj);
	}

	/*!
	 * \brief 设置指定位置的对象
	 * \details 如果该位置已有对象，会释放旧的对象，并设置新对象的引用计数
	 * \param idx 数组索引
	 * \param obj 要设置的对象指针
	 * \param bAutoRetain 是否自动增加引用计数，默认为true
	 */
	void set(uint32_t idx, WTSObject* obj, bool bAutoRetain = true)
	{
		if(idx >= _vec.size() || obj == NULL)
			return;

		if(bAutoRetain)
			obj->retain();

		WTSObject* oldObj = _vec.at(idx);
		if(oldObj)
			oldObj->release();

		_vec[idx] = obj;
	}

	/*!
	 * \brief 追加另一个数组的所有元素
	 * \details 将另一个数组的元素移动到当前数组末尾，源数组会被清空
	 * \param ay 要追加的源数组
	 */
	void append(WTSArray* ay)
	{
		if(ay == NULL)
			return;

		_vec.insert(_vec.end(), ay->_vec.begin(), ay->_vec.end());
		ay->_vec.clear();
	}

	/*!
	 * \brief 清空数组
	 * \details 会减少所有对象的引用计数，并清空数组
	 */
	void clear()
	{
		{
			std::vector<WTSObject*>::iterator it = _vec.begin();
			for (; it != _vec.end(); it++)
			{
				WTSObject* obj = (*it);
				if (obj)
					obj->release();
			}
		}
		
		_vec.clear();
	}

	/*!
	 * \brief 释放数组对象，继承自WTSObject
	 * \details 减少引用计数，当引用计数为0时，清空数组并释放对象本身
	 */
	virtual void release()
	{
		if (m_uRefs == 0)
			return;

		try
		{
			m_uRefs--;
			if (m_uRefs == 0)
			{
				clear();
				delete this;
			}
		}
		catch(...)
		{

		}
	}

	/*!
	 * \brief 获取数组开始位置的迭代器
	 * \return 指向数组开头的正向迭代器
	 */
	Iterator begin()
	{
		return _vec.begin();
	}

	/*!
	 * \brief 获取数组开始位置的常量迭代器
	 * \return 指向数组开头的常量正向迭代器
	 */
	ConstIterator begin() const
	{
		return _vec.begin();
	}

	/*!
	 * \brief 获取数组末尾位置的反向迭代器
	 * \return 指向数组末尾的反向迭代器
	 */
	ReverseIterator rbegin()
	{
		return _vec.rbegin();
	}

	/*!
	 * \brief 获取数组末尾位置的常量反向迭代器
	 * \return 指向数组末尾的常量反向迭代器
	 */
	ConstReverseIterator rbegin() const
	{
		return _vec.rbegin();
	}

	/*!
	 * \brief 获取数组结束位置的迭代器
	 * \return 指向数组结尾的正向迭代器
	 */
	Iterator end()
	{
		return _vec.end();
	}

	/*!
	 * \brief 获取数组结束位置的常量迭代器
	 * \return 指向数组结尾的常量正向迭代器
	 */
	ConstIterator end() const
	{
		return _vec.end();
	}

	/*!
	 * \brief 获取数组开始位置的反向迭代器
	 * \return 指向数组开头的反向迭代器
	 */
	ReverseIterator rend()
	{
		return _vec.rend();
	}

	/*!
	 * \brief 获取数组开始位置的常量反向迭代器
	 * \return 指向数组开头的常量反向迭代器
	 */
	ConstReverseIterator rend() const
	{
		return _vec.rend();
	}

	/*!
	 * \brief 使用自定义函数对数组进行排序
	 * \param func 排序比较函数
	 */
	void	sort(SortFunc func)
	{
		std::sort(_vec.begin(), _vec.end(), func);
	}

protected:
	WTSArray():_holding(false){}
	virtual ~WTSArray(){}

	std::vector<WTSObject*>	_vec;
	std::atomic<bool>		_holding;
};


/*!
 * \brief 有序映射容器模板类
 * 
 * \details 内部基于std::map实现的键值对容器，具有以下特点：
 *          - 模板参数T作为key类型
 *          - 值类型固定为WTSObject指针
 *          - 支持WTSObject引用计数管理
 *          - 按键值自动排序
 *          - 提供STL兼容的迭代器接口
 *          - 线程安全的引用计数管理
 * 
 * \tparam T 键类型，需要支持比较运算符
 * 
 * \author Wesley
 * \date 2020/03/30
 */
template <class T>
class WTSMap : public WTSObject
{
public:
	/*!
	 * \brief 类型定义
	 */
	typedef typename std::map<T, WTSObject*>	_MyType;		///< 内部map类型
	typedef typename _MyType::iterator			Iterator;		///< 正向迭代器
	typedef typename _MyType::const_iterator	ConstIterator;	///< 常量正向迭代器

	/*!
	 * \brief 创建映射容器实例
	 * \details 静态工厂方法，创建新的WTSMap实例
	 * \return 新创建的WTSMap指针
	 */
	static WTSMap<T>*	create()
	{
		WTSMap<T>* pRet = new WTSMap<T>();
		return pRet;
	}

	/*!
	 * \brief 获取映射容器的大小
	 * \return 容器中键值对的数量
	 */
	uint32_t size() const{ return (uint32_t)_map.size(); }

	/*!
	 * \brief 查找指定键对应的对象
	 * \details 返回指定键的对象指针，不增加引用计数，如果键不存在则返回NULL
	 * \param _key 要查找的键
	 * \return 对应的对象指针，不存在则返回NULL
	 */
	WTSObject* get(const T &_key)
	{
		Iterator it = _map.find(_key);
		if(it == _map.end())
			return NULL;

		WTSObject* pRet = it->second;
		return pRet;
	}

	/*!
	 * \brief []操作符重载
	 * \details 用法同get方法
	 * \param _key 要查找的键
	 * \return 对应的对象指针，不存在则返回NULL
	 */
	WTSObject* operator[](const T &_key)
	{
		Iterator it = _map.find(_key);
		if(it == _map.end())
			return NULL;

		WTSObject* pRet = it->second;
		return pRet;
	}

	/*!
	 * \brief 查找指定键对应的对象并增加引用计数
	 * \details 返回指定键的对象指针，会增加引用计数，调用者需要负责释放
	 * \param _key 要查找的键
	 * \return 对应的对象指针（已增加引用计数），不存在则返回NULL
	 */
	WTSObject* grab(const T &_key)
	{
		Iterator it = _map.find(_key);
		if(it == _map.end())
			return NULL;

		WTSObject* pRet = it->second;
		if (pRet)
			pRet->retain();

		return pRet;
	}

	/*!
	 * \brief 添加键值对到映射容器
	 * \details 如果键已存在，会释放旧对象并设置新对象
	 * \param _key 键
	 * \param obj 要添加的对象指针
	 * \param bAutoRetain 是否自动增加引用计数，默认为true
	 */
	void add(T _key, WTSObject* obj, bool bAutoRetain = true)
	{
		if(bAutoRetain && obj)
			obj->retain();

		WTSObject* pOldObj = NULL;
		Iterator it = _map.find(_key);
		if(it != _map.end())
		{
			pOldObj = it->second;
		}

		_map[_key] = obj;

		if (pOldObj) pOldObj->release();
	}

	/*!
	 * \brief 根据键删除一个键值对
	 * \details 如果键存在，会减少对应对象的引用计数
	 * \param _key 要删除的键
	 */
	void remove(T _key)
	{
		Iterator it = _map.find(_key);
		if(it != _map.end())
		{
			WTSObject* obj = it->second;
			_map.erase(it);
			if (obj) obj->release();
		}
	}

	/*!
	 * \brief 获取映射容器开始位置的迭代器
	 * \return 指向容器开头的迭代器
	 */
	Iterator begin()
	{
		return _map.begin();
	}

	/*!
	 * \brief 获取映射容器开始位置的常量迭代器
	 * \return 指向容器开头的常量迭代器
	 */
	ConstIterator begin() const
	{
		return _map.begin();
	}

	/*!
	 * \brief 获取映射容器结束位置的迭代器
	 * \return 指向容器结尾的迭代器
	 */
	Iterator end()
	{
		return _map.end();
	}

	/*!
	 * \brief 获取映射容器结束位置的常量迭代器
	 * \return 指向容器结尾的常量迭代器
	 */
	ConstIterator end() const
	{
		return _map.end();
	}

	/*!
	 * \brief 查找指定键的迭代器
	 * \param key 要查找的键
	 * \return 指向对应元素的迭代器，若不存在则返回end()
	 */
	Iterator find(const T& key)
	{
		return _map.find(key);
	}

	/*!
	 * \brief 查找指定键的常量迭代器
	 * \param key 要查找的键
	 * \return 指向对应元素的常量迭代器，若不存在则返回end()
	 */
	ConstIterator find(const T& key) const
	{
		return _map.find(key);
	}

	/*!
	 * \brief 删除指定迭代器位置的元素
	 * \param it 要删除的迭代器位置
	 */
	void erase(ConstIterator it)
	{
		_map.erase(it);
	}

	/*!
	 * \brief 返回第一个不小于给定键的迭代器
	 * \param key 比较的键
	 * \return 指向第一个不小于key的元素的迭代器
	 */
	Iterator lower_bound(const T& key)
	{
		 return _map.lower_bound(key);
	}

	/*!
	 * \brief 返回第一个不小于给定键的常量迭代器
	 * \param key 比较的键
	 * \return 指向第一个不小于key的元素的常量迭代器
	 */
	ConstIterator lower_bound(const T& key) const
	{
		return _map.lower_bound(key);
	}

	/*!
	 * \brief 返回第一个大于给定键的迭代器
	 * \param key 比较的键
	 * \return 指向第一个大于key的元素的迭代器
	 */
	Iterator upper_bound(const T& key)
	{
	 	 return _map.upper_bound(key);
	}
	 
	/*!
	 * \brief 返回第一个大于给定键的常量迭代器
	 * \param key 比较的键
	 * \return 指向第一个大于key的元素的常量迭代器
	 */
	ConstIterator upper_bound(const T& key) const
	{
		return _map.upper_bound(key);
	}

	WTSObject* last() 
	{
		if(_map.empty())
			return NULL;
		
		return _map.rbegin()->second;
	}
	

	/*!
	 * \brief 清空映射容器
	 * \details 会减少所有对象的引用计数并清空容器
	 */
	void clear()
	{
		Iterator it = _map.begin();
		for(; it != _map.end(); it++)
		{
			it->second->release();
		}
		_map.clear();
	}

	/*!
	 * \brief 释放映射容器对象
	 * \details 减少引用计数，当引用计数为0时，清空容器并释放对象本身
	 */
	virtual void release()
	{
		if (m_uRefs == 0)
			return;

		try
		{
			m_uRefs--;
			if (m_uRefs == 0)
			{
				clear();
				delete this;
			}
		}
		catch(...)
		{

		}
	}

protected:
	WTSMap(){}
	~WTSMap(){}

	std::map<T, WTSObject*>	_map;
};

/*
 *	map容器
 *	内部基于std:map实现
 *	模板参数为key类型
 *	因此使用WTSObject指针
 *	因此WTSObject对象不能共享
 */
template <typename T>
class WTSHashMap : public WTSObject
{
public:
	/*
	 *	类型定义
	 */
	typedef tsl::robin_map<T, WTSObject*>		_MyType;
	typedef typename _MyType::const_iterator	ConstIterator;

	/*
	 *	创建哈希映射容器实例
	 */
	static WTSHashMap<T>*	create()
	{
		WTSHashMap<T>* pRet = new WTSHashMap<T>();
		return pRet;
	}

	/*
	 *	获取哈希映射容器的大小
	 */
	uint32_t size() const{return (uint32_t)_map.size();}

	/*
	 *	查找指定键对应的对象
	 */
	WTSObject* get(const T &_key)
	{
		auto it = _map.find(_key);
		if(it == _map.end())
			return NULL;

		WTSObject* pRet = it->second;
		return pRet;
	}

	/*
	 *	查找指定键对应的对象并增加引用计数
	 */
	WTSObject* grab(const T &_key)
	{
		auto it = _map.find(_key);
		if(it == _map.end())
			return NULL;

		WTSObject* pRet = it->second;
		pRet->retain();
		return pRet;
	}

	/*
	 *	添加键值对到哈希映射容器
	 */
	void add(const T &_key, WTSObject* obj, bool bAutoRetain = true)
	{
		if (bAutoRetain && obj)
			obj->retain();

		WTSObject* pOldObj = NULL;
		auto it = _map.find(_key);
		if (it != _map.end())
		{
			pOldObj = it->second;
		}

		_map[_key] = obj;

		if (pOldObj) pOldObj->release();
	}

	/*
	 *	根据键删除一个键值对
	 */
	void remove(const T &_key)
	{
		auto it = _map.find(_key);
		if(it != _map.end())
		{
			it->second->release();
			_map.erase(it);
		}
	}

	/*
	 *	获取哈希映射容器开始位置的常量迭代器
	 */
	ConstIterator begin() const
	{
		return _map.begin();
	}

	/*
	 *	获取哈希映射容器结束位置的常量迭代器
	 */
	ConstIterator end() const
	{
		return _map.end();
	}

	/*
	 *	查找指定键的常量迭代器
	 */
	ConstIterator find(const T& key) const
	{
		return _map.find(key);
	}

	/*
	 *	清空哈希映射容器
	 */
	void clear()
	{
		ConstIterator it = _map.begin();
		for(; it != _map.end(); it++)
		{
			it->second->release();
		}
		_map.clear();
	}

	/*
	 *	释放哈希映射容器对象
	 */
	virtual void release()
	{
		if (m_uRefs == 0)
			return;

		try
		{
			m_uRefs--;
			if (m_uRefs == 0)
			{
				clear();
				delete this;
			}
		}
		catch (...)
		{

		}
	}

protected:
	WTSHashMap(){}
	virtual ~WTSHashMap(){}

	//std::unordered_map<T, WTSObject*>	_map;
	tsl::robin_map<T, WTSObject*>	_map;
};

//////////////////////////////////////////////////////////////////////////
//WTSQueue
class WTSQueue : public WTSObject
{
public:
	typedef std::deque<WTSObject*>::iterator Iterator;
	typedef std::deque<WTSObject*>::const_iterator ConstIterator;

	static WTSQueue* create()
	{
		WTSQueue* pRet = new WTSQueue();
		return pRet;
	}

	void pop()
	{
		_queue.pop_front();
	}

	void push(WTSObject* obj, bool bAutoRetain = true)
	{
		if (obj && bAutoRetain)
			obj->retain();

		_queue.emplace_back(obj);
	}

	WTSObject* front(bool bRetain = true)
	{
		if(_queue.empty())
			return NULL;

		WTSObject* obj = _queue.front();
		if(bRetain)
			obj->retain();

		return obj;
	}

	WTSObject* back(bool bRetain = true)
	{
		if(_queue.empty())
			return NULL;

		WTSObject* obj = _queue.back();
		if(bRetain)
			obj->retain();

		return obj;
	}

	uint32_t size() const{ return (uint32_t)_queue.size(); }

	bool	empty() const{return _queue.empty();}

	void release()
	{
		if (m_uRefs == 0)
			return;

		try
		{
			m_uRefs--;
			if (m_uRefs == 0)
			{
				clear();
				delete this;
			}
		}
		catch (...)
		{

		}
	}

	void clear()
	{
		Iterator it = begin();
		for(; it != end(); it++)
		{
			(*it)->release();
		}
		_queue.clear();
	}

	/*
	 *	获取队列开始位置的迭代器
	 */
	Iterator begin()
	{
		return _queue.begin();
	}

	ConstIterator begin() const
	{
		return _queue.begin();
	}

	void swap(WTSQueue* right)
	{
		_queue.swap(right->_queue);
	}

	/*
	 *	获取队列结束位置的迭代器
	 */
	Iterator end()
	{
		return _queue.end();
	}

	ConstIterator end() const
	{
		return _queue.end();
	}

protected:
	WTSQueue(){}
	virtual ~WTSQueue(){}

	std::deque<WTSObject*>	_queue;
};

NS_WTP_END